home *** CD-ROM | disk | FTP | other *** search
/ Aminet 40 / Aminet 40 (2000)(Schatztruhe)[!][Dec 2000].iso / Aminet / dev / lang / Python16_Src.lha / Python16_Source / Parser / parsetok.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-08-03  |  3.4 KB  |  177 lines

  1. /* Parser-tokenizer link implementation */
  2.  
  3. #include "pgenheaders.h"
  4. #include "tokenizer.h"
  5. #include "node.h"
  6. #include "grammar.h"
  7. #include "parser.h"
  8. #include "parsetok.h"
  9. #include "errcode.h"
  10.  
  11. int Py_TabcheckFlag;
  12.  
  13.  
  14. /* Forward */
  15. static node *parsetok Py_PROTO((struct tok_state *, grammar *, int,
  16.                  perrdetail *));
  17.  
  18. /* Parse input coming from a string.  Return error code, print some errors. */
  19.  
  20. node *
  21. PyParser_ParseString(s, g, start, err_ret)
  22.     char *s;
  23.     grammar *g;
  24.     int start;
  25.     perrdetail *err_ret;
  26. {
  27.     struct tok_state *tok;
  28.  
  29.     err_ret->error = E_OK;
  30.     err_ret->filename = NULL;
  31.     err_ret->lineno = 0;
  32.     err_ret->offset = 0;
  33.     err_ret->text = NULL;
  34.  
  35.     if ((tok = PyTokenizer_FromString(s)) == NULL) {
  36.         err_ret->error = E_NOMEM;
  37.         return NULL;
  38.     }
  39.  
  40.     if (Py_TabcheckFlag || Py_VerboseFlag) {
  41.         tok->filename = "<string>";
  42.         tok->altwarning = (tok->filename != NULL);
  43.         if (Py_TabcheckFlag >= 2)
  44.             tok->alterror++;
  45.     }
  46.  
  47.     return parsetok(tok, g, start, err_ret);
  48. }
  49.  
  50.  
  51. /* Parse input coming from a file.  Return error code, print some errors. */
  52.  
  53. node *
  54. PyParser_ParseFile(fp, filename, g, start, ps1, ps2, err_ret)
  55.     FILE *fp;
  56.     char *filename;
  57.     grammar *g;
  58.     int start;
  59.     char *ps1, *ps2;
  60.     perrdetail *err_ret;
  61. {
  62.     struct tok_state *tok;
  63.  
  64.     err_ret->error = E_OK;
  65.     err_ret->filename = filename;
  66.     err_ret->lineno = 0;
  67.     err_ret->offset = 0;
  68.     err_ret->text = NULL;
  69.  
  70.     if ((tok = PyTokenizer_FromFile(fp, ps1, ps2)) == NULL) {
  71.         err_ret->error = E_NOMEM;
  72.         return NULL;
  73.     }
  74.     if (Py_TabcheckFlag || Py_VerboseFlag) {
  75.         tok->filename = filename;
  76.         tok->altwarning = (filename != NULL);
  77.         if (Py_TabcheckFlag >= 2)
  78.             tok->alterror++;
  79.     }
  80.  
  81. #ifdef macintosh
  82.     {
  83.         int tabsize = guesstabsize(filename);
  84.         if (tabsize > 0)
  85.             tok->tabsize = tabsize;
  86.     }
  87. #endif
  88.  
  89.     return parsetok(tok, g, start, err_ret);
  90. }
  91.  
  92. /* Parse input coming from the given tokenizer structure.
  93.    Return error code. */
  94.  
  95. static node *
  96. parsetok(tok, g, start, err_ret)
  97.     struct tok_state *tok;
  98.     grammar *g;
  99.     int start;
  100.     perrdetail *err_ret;
  101. {
  102.     parser_state *ps;
  103.     node *n;
  104.     int started = 0;
  105.  
  106.     if ((ps = PyParser_New(g, start)) == NULL) {
  107.         fprintf(stderr, "no mem for new parser\n");
  108.         err_ret->error = E_NOMEM;
  109.         return NULL;
  110.     }
  111.  
  112.     for (;;) {
  113.         char *a, *b;
  114.         int type;
  115.         int len;
  116.         char *str;
  117.  
  118.         type = PyTokenizer_Get(tok, &a, &b);
  119.         if (type == ERRORTOKEN) {
  120.             err_ret->error = tok->done;
  121.             break;
  122.         }
  123.         if (type == ENDMARKER && started) {
  124.             type = NEWLINE; /* Add an extra newline */
  125.             started = 0;
  126.         }
  127.         else
  128.             started = 1;
  129.         len = b - a; /* XXX this may compute NULL - NULL */
  130.         str = PyMem_NEW(char, len + 1);
  131.         if (str == NULL) {
  132.             fprintf(stderr, "no mem for next token\n");
  133.             err_ret->error = E_NOMEM;
  134.             break;
  135.         }
  136.         if (len > 0)
  137.             strncpy(str, a, len);
  138.         str[len] = '\0';
  139.         if ((err_ret->error =
  140.              PyParser_AddToken(ps, (int)type, str,
  141.                        tok->lineno)) != E_OK) {
  142.             if (err_ret->error != E_DONE)
  143.                 PyMem_DEL(str);
  144.             break;
  145.         }
  146.     }
  147.  
  148.     if (err_ret->error == E_DONE) {
  149.         n = ps->p_tree;
  150.         ps->p_tree = NULL;
  151.     }
  152.     else
  153.         n = NULL;
  154.  
  155.     PyParser_Delete(ps);
  156.  
  157.     if (n == NULL) {
  158.         if (tok->lineno <= 1 && tok->done == E_EOF)
  159.             err_ret->error = E_EOF;
  160.         err_ret->lineno = tok->lineno;
  161.         err_ret->offset = tok->cur - tok->buf;
  162.         if (tok->buf != NULL) {
  163.             int len = tok->inp - tok->buf;
  164.             err_ret->text = PyMem_NEW(char, len + 1);
  165.             if (err_ret->text != NULL) {
  166.                 if (len > 0)
  167.                     strncpy(err_ret->text, tok->buf, len);
  168.                 err_ret->text[len] = '\0';
  169.             }
  170.         }
  171.     }
  172.  
  173.     PyTokenizer_Free(tok);
  174.  
  175.     return n;
  176. }
  177.